package com.iwhalecloud.bss.kite.cucc.service.goods;

import com.iwhalecloud.bss.kite.common.util.KiteDateUtils;
import com.iwhalecloud.bss.kite.cucc.client.api.goods.IAdditionalOfferComputeService;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.common.util.DateUtils;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.dataservice.entity.DcPublic;
import com.iwhalecloud.bss.kite.manager.inst.KiteOfferInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteProdInst;
import com.iwhalecloud.bss.kite.manager.scene.service.QuerySceneInstService;
import com.iwhalecloud.bss.kite.service.scene.operate.OperateSceneAdditionalOfferInstService;
import com.ztesoft.bss.common.exception.BssException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Service
public class AdditionalOfferComputeService implements IAdditionalOfferComputeService {
    /***
     * 传输计划档位属性编码
     */
    private static final String FIELD_LEVEL_CODE="200002163";
    /***
     * 传输计划结束时间
     */
    private static final String TRANSFER_FIELD_END_DT="200002051";
    /***
     * 传输计划开始时间START
     */
    private static final String TRANSFER_FIELD_START_DT="200002050";
    /***
     * 传输计划自定义取消费
     */
    private static final String TRANSFER_FIELD_CUSTOMER_FEE="200002164";

    /***
     * 临时取消费属性编码
     */
    private static final String CANCEL_FIELD_FEE="200000169";

    /***
     * 300分钟之前标准资费
     */
    private static final String BEFOR_300_FIELD_FEE="200000169";
    /***
     * 300分钟之前折扣
     */
    private static final String BEFOR_300_FIELD_DISCOUNT="200000169";
    /***
     * 300分钟之前折后费用
     */
    private static final String BEFOR_300_FIELD_DISCOUNT_FEE="200000169";
    /***
     * 300分钟之后标准资费
     */
    private static final String AFTER_300_FIELD_FEE="200000169";
    /***
     * 300分钟之后折扣
     */
    private static final String AFTER_300_FIELD_IDSCOUNT="200000169";

    /***
     * 时长，大于时长按标准资费2计算，小于等于时长按标准资费1计算
     */
    private static final String STANDARD_TIME_FIELD="200000169";

    /***
     * 300分钟之前折后费用
     */
    private static final String AFTER_300_FIELD_DISCOUNT_FEE="200000169";

    /***
     * 档位1：传送前48小时之外不收取
     */
    private static final String FIELD_LEVEL_1="100003351";
    /***
     * 档位2：传送前48至24小时之内，收取此传输计划全部租费的30%
     */
    private static final String FIELD_LEVEL_2="100003352";
    /***
     * 档位3：传送前24至2小时之内，收取此传输计划全部租费的50%
     */
    private static final String FIELD_LEVEL_3="100003353";
    /***
     * 档位4：传送前2小时之内，收取此传输计划全部租费的100%
     */
    private static final String FIELD_LEVEL_4="100003354";
    /***
     * 其它：自定义收取金额（元），录入备注信息
     */
    private static final String FIELD_LEVEL_0="100003362";


    @Autowired
    private QuerySceneInstService querySceneInstService;

    @Autowired
    private OperateSceneAdditionalOfferInstService operateSceneAdditionalOfferInstService;

    /***
     * 计算临时取消费
     * @param sceneInstId
     * @param transferPlanInstId
     * @param custId
     * @param staffId
     */
    @Override
    public void computeTransferCancelFee(String sceneInstId, String transferPlanInstId,String custId,String staffId){
        //临时取消费相关配置信息
        DcPublic dcPublic= DcPublicCache.get(LocalKeyConsts.ADD_OFFER_STYPE, "4");
        KiteProdInst prodInst = querySceneInstService.getProdInst(custId, transferPlanInstId);
        String feelevel=prodInst.getAttrValue(FIELD_LEVEL_CODE);

        String offerInstId= querySceneInstService.getExtParameterValue(sceneInstId, "mainOfferInstId");
        List<KiteOfferInst> oferInstList=querySceneInstService.listAdditionalOfferInstsFromOfferInst(custId, offerInstId);
        KiteOfferInst cancelFeeInst=oferInstList.stream().filter(item->dcPublic.getPcode().equals(item.getSpecId())).findFirst().orElse(null);
        KiteOfferInst timeFeeInst=oferInstList.stream().filter(item->dcPublic.getCodea().equals(item.getSpecId())).findFirst().orElse(null);

        if (cancelFeeInst==null||timeFeeInst==null){
            BssException.throwOut("41301002", "S-SYS-00027", "临时取消费实例获取失败");
        }
        //如果自定义取消费，则直接累加到临时取消费中
        BigDecimal originFee=new BigDecimal(cancelFeeInst.getAttrValue(CANCEL_FIELD_FEE));
        BigDecimal addFee=new BigDecimal("0");
        if(FIELD_LEVEL_0.equals(feelevel)){
            addFee=new BigDecimal(prodInst.getAttrValue(TRANSFER_FIELD_CUSTOMER_FEE));
        }else if(FIELD_LEVEL_1.equals(feelevel)){
            addFee=new BigDecimal("0");
        }else{
            Date endDt=KiteDateUtils.parseStrToDate(prodInst.getAttrValue(TRANSFER_FIELD_END_DT),DateUtils.DEFAULT_PATTERN);
            Date startDt=KiteDateUtils.parseStrToDate(prodInst.getAttrValue(TRANSFER_FIELD_START_DT),DateUtils.DEFAULT_PATTERN);
            Long  time=dateBetweenMin(startDt,endDt);
            BigDecimal  firstFee=new BigDecimal(timeFeeInst.getAttrValue(BEFOR_300_FIELD_DISCOUNT_FEE));
            BigDecimal  lastFee=new BigDecimal(timeFeeInst.getAttrValue(AFTER_300_FIELD_DISCOUNT_FEE));
            Long standardTime=Optional.ofNullable(timeFeeInst.getAttrValue(STANDARD_TIME_FIELD)).map(Long::parseLong).orElse(0L);
            BigDecimal totalFee=computePlanFee(time,standardTime,firstFee,lastFee);
            if(FIELD_LEVEL_2.equals(feelevel)){
                addFee=totalFee.multiply(new BigDecimal("0.3"));
            }else if(FIELD_LEVEL_3.equals(feelevel)){
                addFee=totalFee.multiply(new BigDecimal("0.5"));
            }else if(FIELD_LEVEL_4.equals(feelevel)){
                addFee=totalFee;
            }
        }
        BigDecimal cancelFee=originFee.add(addFee);
        operateSceneAdditionalOfferInstService
            .updateAdditionalOfferAttr(sceneInstId, cancelFeeInst.getSpecId(), CANCEL_FIELD_FEE, String.valueOf(cancelFee), String.valueOf(cancelFee), custId, staffId);
    }

    private  Long  dateBetweenMin(Date start,Date end){
        return (end.getTime()-start.getTime())/(1000*60);
    }

    /***\
     *
     * @param time
     * @param standandTime 标准时长，默认300
     * @param firstFee 标准时长之前的每分钟费用
     * @param lastFee  标准时长后分钟后每分钟费用
     * @return
     */
    private  BigDecimal  computePlanFee(Long time,Long standandTime,BigDecimal firstFee,BigDecimal lastFee){
        if(time<=standandTime){
            return firstFee.multiply(new BigDecimal(time));
        }else{
            BigDecimal standFee= firstFee.multiply(new BigDecimal(standandTime));
            //超过标准时长后的时间
            Long afterTime=time-standandTime;
            BigDecimal overFee=lastFee.multiply(new BigDecimal(afterTime));
            return  standFee.add(overFee);

        }
    }


}
